<?php
define('IN_SYSTEM',true);
define('IS_POST', (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST'));
error_reporting(0);
class Base {
	var $var = array() ;
	function base() {
		$this->_init();
		$this->_init_config();
	}

	function _init_all() {
		static $inited;
		if(!$inited) {
			$this->_init_cache();
			$this->_init_anony();
			$this->_init_db();
			$this->_init_user();
			$this->_init_theme();
			$inited = true;
		}
	}

	function _init() {
		if(phpversion() < '5.3.0') {
			set_magic_quotes_runtime(0);
		}
		function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0');
		define('TIMESTAMP', $_SERVER['REQUEST_TIME']);
		if (ini_get('register_globals')) {
			$allowed = array('_ENV' => 0, '_GET' => 1, '_POST' => 1, '_COOKIE' => 1, '_FILES' => 1, '_SERVER' => 1, '_REQUEST' => 1, 'GLOBALS' => 0);
			foreach ($GLOBALS as $key => $value) {
			      	if (!isset($allowed[$key])) {
			      		$GLOBALS[$key] = NULL;
			        	unset($GLOBALS[$key]);
			      	}
		    	}
		    	$allowed = NULL;
		    	unset($allowed);
		}
		if (isset($_GET['GLOBALS']) || isset($_POST['GLOBALS']) || isset($_COOKIE['GLOBALS']) || isset($_SERVER['GLOBALS']) || isset($_SESSION['GLOBALS']) || isset($_FILES['GLOBALS'])) {
			exit;
		}
    		$base_url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http'). '://'. $_SERVER['HTTP_HOST'].'/';
    		if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
    			$base_url .= "$dir/";
    		}
		define('BASE_URL', $base_url);
		define('BASE_ROOT', substr(dirname(__FILE__),0,-8));
		
		$dir = $base_url = NULL;
		unset($dir,$base_url);
		include(BASE_ROOT.'./includes/function.php');
		if ( !get_magic_quotes_gpc() ) {
			$_GET = add_slashes($_GET);
			$_POST = add_slashes($_POST);
			$_COOKIE = add_slashes($_COOKIE);
		}
		define('ISROBOT', checkrobot());
        	global $_G;
		$_G = array(
			'uid' => 0,
			'username' => '',
			'timestamp' => TIMESTAMP,
			'ip' => get_client_ip(),
			'php_self' => htmlspecialchars($_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['PHP_SELF']),
			'request_uri' => $_SERVER['REQUEST_URI'],
			'gourl' => isset($_REQUEST['gourl']) ? $_REQUEST['gourl'] : (isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:''),
			'users' => array(),
			'style' => array(),
			'cache' => array(),
			'session' => array(),
			'lang' => array(),
		);
		$this->var = & $_G;
	}

	function _init_config() {
		$setting_file = $this->_get_setting_file();
		include(BASE_ROOT.$setting_file);
		!defined('DATA_DIR') && define('DATA_DIR','');
		define('CACHE_ROOT',BASE_ROOT.DATA_DIR.'./cache/');
		@header("content-Type: text/html; charset=".CHARSET);
	}
	
	function _init_anony(){
		if ( (!getGP('auth','c')) && !IS_POST){
			$url = md5($this->var['request_uri']);
			$data = $this->var['cache']->get($url,'pages');
			if($data){
				echo $data;
				exit;
			}
			ob_start();
			$this->var['needcache'] = $url;
		}
	}
	function _init_db() {
		 $this->var['db'] = new Mysql();
	}

	function _init_session() {
		new session();
	}

	function _init_user() {
		$this->var['userobj'] = new User();
		$this->var['userobj']->init_user();
	}
	function _init_cache() {
		$this->var['cache'] = new Cache();
		//预留缓存接口
	}
	function _init_theme() {
		$this->var['settings'] = $this->var['cache']->get('settings');
		if(!$this->var['settings']) {
			recache('settings');
			$this->var['settings'] = $this->var['cache']->get('settings');
		}
		if(isset($this->var['settings']['theme'])) {
			define('THEME_ROOT',BASE_ROOT.'themes/'.$this->var['settings']['theme'].'/');
			define('THEME_URL',BASE_URL.'themes/'.$this->var['settings']['theme'].'/');
		} else {
			define('THEME_ROOT',BASE_ROOT.'themes/default/');
			define('THEME_URL',BASE_URL.'themes/default/');
		}
		if(file_exists(THEME_ROOT.'theme.func.php')) {
			include(THEME_ROOT.'theme.func.php');
		}
	}
	function _get_setting_file() {
		static $conf = '';
		if ($conf) {
	  		return $conf;
	  	}
		$confdir = 'sites';
	  	$uri = explode('/', $_SERVER['REQUEST_URI'] ? $_SERVER['REQUEST_URI'] : $_SERVER['SCRIPT_NAME']);
	  	$server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
	  	for ($i = count($uri) - 1; $i > 0; $i--) {
		    	for ($j = count($server); $j > 0; $j--) {
			      	$dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
			      	if (file_exists(BASE_ROOT."$confdir/$dir/config.php")) {
			        	$conf = "$confdir/$dir/config.php";
			        	$uri = $server = $i = $j = $dir = NULL;
			  		unset($uri,$server,$i,$j,$dir);
			        	return $conf;
			      	}
		    	}
	  	}
	  	$conf = "$confdir/default/config.php";
	  	$uri = $server = $i = $j = $dir = $confdir = NULL;
	  	unset($uri,$server,$i,$j,$dir,$confdir);
	  	return $conf;
	}
}

class Mysql {
	var $link;
	var $querynum = 0;
	var $querylog = array();
	function connect($host,$user,$pwd,$dbname,$pconnect = false) {
		$this->link = $pconnect ? @mysql_pconnect($host,$user,$pwd) : @mysql_connect($host,$user,$pwd);
		if ( !$this->link ) {
			$this->halt('Connect to MySQL failed!');
		}
		if ( !mysql_select_db($dbname, $this->link) ) {
			$this->halt('Cannot use database!');
		}
		if ($this->version() > '4.1') {
			mysql_query('SET NAMES '.strtolower(str_replace('-','',CHARSET)).';',$this->link);
		}
		return true;
	}
	function query($sql, $unbuffer = false ) {
		static $db;
		if(!$db){
			$db = $this->connect(DB_HOST, decrypt(DB_USER,DB_NAME), decrypt(DB_PASS,DB_NAME), DB_NAME, DB_PCONNECT);
		}
		if ( $unbuffer && function_exists('mysql_unbuffered_query') ) {
			$query = @mysql_unbuffered_query($sql, $this->link);
		} else {
			$query = @mysql_query($sql,$this->link);
		}
		//$this->querynum ++;
		//$this->querylog[] = $sql;
		!$query && $this->halt('Query Error: ',$sql);
		return $query;
	}
	function fetch_array($query,$result_type = MYSQL_ASSOC) {
		return mysql_fetch_array($query,$result_type);
	}
	function fetch_one_array($sql) {
		$query = $this->query($sql);
		return $this->fetch_array($query);
	}
	function fetch_all($sql) {
		$result = array();
		$query = $this->query($sql);
		while($row = $this->fetch_array($query)) {
			$result[] = $row;
		}
		return $result;
	}
	function result ($sql, $row = 0) {
		$query = $this->query($sql);
		return @mysql_result($query, $row);
	}

	function free_result($query) {
		return mysql_free_result($query);
	}
	function insert($table, $data, $replace = false) {
		$table = DB_PREFIX.$table;
		$method = $replace ? 'REPLACE ' : 'INSERT';
		$fields = $values = $split = '';
		foreach ( $data as $key => $val ) {
			$fields .= $split."`$key`";
			$values .= $split."'$val'";
			$split = ', ';
		}
		$sql = "$method INTO `$table` ($fields) VALUES ($values)";
		$this->query($sql);
		return $this->insert_id();
	}
	function update($table, $data, $where) {
		$table = DB_PREFIX.$table;
		$updatesql = $wheresql = $split = '';
		foreach ( $data as $key => $val ) {
			$updatesql .= $split."`$key` = '$val'";
			$split = ', ';
		}
		if ( empty($where) ) {
			$wheresql = '1';
		} else if( !is_array($where) ){
			$wheresql = $where;
		} else {
			$split = '';
			foreach ($where as $key => $val ) {
				$wheresql .= $split."`$key` = '$val'";
				$split = ' AND ';
			}
		}
		$sql = "UPDATE `$table` SET $updatesql WHERE $wheresql";
		$this->query($sql);
		return $this->affected_rows();
	}
	function delete($table, $where) {
		$table = DB_PREFIX.$table;
		$updatesql = $wheresql = $split = '';
		if ( empty($where) ) {
			$wheresql = '1';
		} else if( !is_array($where) ){
			$wheresql = $where;
		} else {
			$split = '';
			foreach ($where as $key => $val ) {
				$wheresql .= $split."`$key` = '$val'";
				$split = ' AND ';
			}
		}
		$sql = "DELETE FROM `$table` WHERE $wheresql";
		$this->query($sql);
		return $this->affected_rows();
	}
	function fetch($table, $field='*', $where=null, $order=null,$limit = null) {
		$table = DB_PREFIX.$table;
		$fieldsql = $wheresql = $split = '';
		foreach ( (array)$field as  $val ) {
			$fieldsql .= $split."$val";
			$split = ', ';
		}
		if ( empty($where) ) {
			$wheresql = '1';
		} else if( !is_array($where) ){
			$wheresql = $where;
		} else {
			$split = '';
			foreach ((array)$where as $key => $val ) {
				$wheresql .= $split."`$key` = '$val'";
				$split = ' AND ';
			}
		}
		$order && $order = ' ORDER BY '.$order;
		$limit && $limit = " LIMIT 0,$limit "; 
		$query = $this->query("SELECT $fieldsql FROM `$table` WHERE $wheresql $order $limit");
		if($this->affected_rows() > 1) {
			while($row = $this->fetch_array($query)) {
				$result[] = $row;
			}
		}else{
			$result = $this->fetch_array($query);
		}
		return $result;
	}
	function insert_id() {
		return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);
	}

	function num_fields($query) {
		return mysql_num_fields($query);
	}

	function num_rows($query) {
		return mysql_num_rows($query);
	}

	function affected_rows() {
		return mysql_affected_rows($this->link);
	}

	function close() {
		return @mysql_close($this->link);
	}

	function version() {
		return mysql_get_server_info($this->link);
	}
	function page_query($sql='',$limit=10) {
		$page = getGP('page');;
		$page = max(1, intval($page));
		$offset = ($page - 1) * $limit;
		return $this->query($sql." LIMIT $offset ,$limit");
	}
	function halt($msg = '',$sql = '') {
		$output = '<div style="font-size:12px;font-family:Verdana">msg:'.$msg.'<br />sql:'.$sql.'<br />errno:'.mysql_errno().'<br />error:'.mysql_error().'</div>';
		exit($output);
	}
	function vd_query($sql=null) {
		echo $sql;
		die ();
	}
}
class session {
	function session() {
		session_set_save_handler('sess_open', 'sess_close', 'sess_read', 'sess_write', 'sess_destroy_sid', 'sess_gc');
		session_start();
	}
}

class mcache {
	var $_memcache = null;
	function __construct(){
    		global $_G;
    		$this->mcache($_G['conf']['mcache']);
	}
	function mcache($conf){
		$this->connect($conf);
	}
	function connect($conf){
		if (empty($conf)){
			return false;
        	}
	        $this->_memcache = new Memcache;
	        return $this->_memcache->connect($conf['host'], $conf['port']);
    	}
	function set($key, $value, $ttl = null){
		return $this->_memcache->set($key, $value, $ttl);
	}

	function &get($key){
		return $this->_memcache->get($key);
	}

	function clear(){
		return $this->_memcache->flush();
	}

	function delete($key){
		return $this->_memcache->delete($key);
	}
}

class Cache {
	function set($key, $data,$type=null, $time = 0){
	        $cache_file = $this->cache_path($key,$type);
	        $cache_data = "<?php\r\n";
	        if( $time )$cache_data .=   'if(filemtime(__FILE__) + ' . ($time*60) . ' < time())return false;' . "\r\n";
	        $data = var_export($data,true);
	        $data = strtr($data, array('stdClass::__set_state' => '(object) '));
	        $cache_data .= "\r\nreturn " . $data .  ";\r\n";
	        $cache_data .= "\r\n?>";
	
	        return file_put_contents($cache_file, $cache_data, LOCK_EX);
	}
	function get($key,$type=null){
	        $cache_file = $this->cache_path($key,$type);
	        if (!is_file($cache_file)){
	            return false;
	        }
	        $data = include($cache_file);
	
	        return $data;
	}
	function cache_path($key,$type=NULL) {
		!$key && die('not cache key for type '.$type);
		if($type){
			if(!is_dir(CACHE_ROOT.$type)){
				make_dir(CACHE_ROOT.$type, 0777);
			}
			return CACHE_ROOT.$type.'/'.$type.'_'.$key.'.php' ;
		}
		return CACHE_ROOT.'cache_'.$key.'.php' ;
	}
	function del($key,$type=null) {
		$cache_file = $this->cache_path($key,$type);
	  	@unlink($cache_file);
	}
}

class lang {
	static function get($key,$mod=null) {
		static $lang = array();
		if(isset($lang[$key])) {
			return $lang[$key];
		}
		$langdir = defined('LANG')?LANG:'utf8';
		if(empty($lang)) {
			$lang = include(BASE_ROOT.'./languages/'.$langdir.'/base.inc') ;
		}
		if($mod && file_exists(BASE_ROOT.'./languages/'.$langdir.'/lang_'.$mod.'.inc')) {
			$lang_mod = include(BASE_ROOT.'./languages/'.$langdir.'/lang_'.$mod.'.inc') ;
			$lang = array_merge($lang,(array)$lang_mod);
		}
		if(isset($lang[$key])) {
			return $lang[$key];
		}else {
			return $key;
		}
	}
	static function load($mod=null) {
		static $lang = array();
		$langdir = defined('LANG')?LANG:'utf8';
		if(empty($lang)) {
			$lang = include(BASE_ROOT.'./languages/'.$langdir.'/base.inc') ;
		}
		if($mod && file_exists(BASE_ROOT.'./languages/'.$langdir.'/lang_'.$mod.'.inc')) {
			$lang_mod = include(BASE_ROOT.'./languages/'.$langdir.'/lang_'.$mod.'.inc') ;
			$lang = array_merge($lang,(array)$lang_mod);
		}
		return $lang;
	}
}

class User {
	function init_user() {
		global $_G;
		if ( !$auth = getGP('auth','c') ){
			define('ISADMIN',false); 
			!isset($_G['groupid']) && $_G['groupid'] = 2;
			$_G['usergroup'] = $_G['cache']->get('usergroup_'.$_G['groupid']);
			if ( !$_G['usergroup'] ) {
				recache('usergroups');
				$_G['usergroup'] = $_G['cache']->get('usergroup_'.$_G['groupid']);
			}
			return false;
		}
		list($uid, $password ) = explode("\t", authcode($auth, 'DECODE'));
		if ( is_numeric($uid) ) {
			$user = $this->get_user_byid($uid);
			if($password == md5($user['password'].$_G['ip'].$user['lastlogin'])) {
				$_G['users'] = $user;
				$_G['uid'] = $user['uid'];
				$_G['groupid'] = $user['groupid'];
				$_G['username'] = $user['username'];
			}else{
				$this->logout();
				error(l('Account login in other place'));
			}
		}
		if ( !$_G['uid'] ) {
			define('ISADMIN',false); 
			$this->logout();
		}
		$_G['groupid'] or $_G['groupid'] = 2;
		$_G['usergroup'] = $_G['cache']->get('usergroup_'.$_G['groupid']);
		if ( !$_G['usergroup'] ) {
			recache('usergroups');
			$_G['usergroup'] = $_G['cache']->get('usergroup_'.$_G['groupid']);
		}
		if( $user['shopid'] ) $_G['store'] = $_G['db']->fetch('shops','*',array('shopid' => $user['shopid']));
		if( $_G['store']['status']<1 ) $_G['users']['shopid'] = 0;
		define('ISADMIN',is_admin()); 
		$user = array();unset($user);
	}
	function get_user_byid($uid) {
		global $_G;
		return $_G['db']->fetch('users','*',array('uid' => $uid));
	}
	function get_user_byname($name) {
		global $_G;
		return $_G['db']->fetch('users','*',array('username' => $name));
	}
	//返回1 登录成功, -1 用户不存在, -2 密码错误, -3 锁定
	function login($username, $password, $remember = 0) {
		if ( empty($username) || empty($password) ) return 0;
		global $_G;
		$user = $_G['db']->fetch('users','uid,password,authkey,logincount,status',array('username' => $username));
		if ( $user ) {
			if ( $user['password'] == password($password,$user['authkey']) ) {
				$auth = authcode("$user[uid]\t".md5($user['password'].$_G['ip'].TIMESTAMP));
				set_cookie('auth', $auth, $remember ? 86400 * 30 : 0);
				$this->update($user['uid'], array('lastlogin' => TIMESTAMP,'logincount' => $user['logincount']+1,'ip' => $_G['ip']));
				if ( !$user['status'] ) return -3;
				return 1;
			}
			return -2;
		}
		return -1;
	}
	/*获取用户信息*/
	function user_load($array = array()) {
		global $_G;
		foreach($array as $key => $value) {
			if($key == 'password') {
				$password= $value;
				unset($array[$key]);
			}
		}
  		$user = $_G['db']->fetch('users','*',$array);
  		if(isset($password) && ($user['password'] !== password($password,$user['authkey']))) {
  			$user = array();
  		}
  		return $user;
	}
	
	function user_group($conditon=array()) {
		global $_G;
		return $_G['db']->fetch('usergroups', '*',$conditon);
	}
	
	function update($uid, $updatearr) {
		global $_G;
		return $_G['db']->update('users', $updatearr, array('uid' => $uid));
	}
	
	function i_can($key) {
		return isset($this->var['usergroup']['access'][$key])?$this->var['usergroup']['access'][$key]:false;
	}

	function logout() {
		set_cookie('auth');
	}
	
	function add_session($data) {
		$data['ip'] = ip2long(get_onlineip());
		$this->db->insert('session', $data, true);
	}
	
	function user_save($user, $array = array()) {
		global $_G;
  		$user_fields = $this->user_fields();
  		if (isset($user['uid'])) {
  			if(isset($array['password'])) {
	    			$array['authkey'] = random(5);
	    			$array['password'] = password(trim($array['password']),$array['authkey']);
	    		}
	  		foreach ($array as $key => $value) {
	    			if(!in_array($key,$user_fields)) {
	    				$array[$key] = null;
	    				unset($array[$key]);
	    			}
	    		}
	    		$this->update($user['uid'],$array);
	    		
	    		$user = $this->user_load(array('uid' => $user['uid']));
  		} else {
			if (!isset($array['regtime'])) {
      				$array['regtime'] = time();
    			}
	    		if(isset($array['password'])) {
	    			$array['authkey'] = random(5);
	    			$array['password'] = password(trim($array['password']),$array['authkey']);
	    		}
	    		foreach ($array as $key => $value) {
	    			if(!in_array($key,$user_fields)) {
	    				$array[$key] = null;
	    				unset($array[$key]);
	    			}
	    		}
	    		$uid = $_G['db']->insert('users',$array);
	    		$user = $this->user_load(array('uid' => $uid));
	    		$_G['db']->insert('user_stat',array('uid'=>$user['uid']));
  		}
  		return $user;
	}

	function user_fields() {
		global $_G;
		static $fields;
		if (!$fields) {
		    	$user = $this->user_load(array('uid' => 1));
		    	if (is_array($user) && $user['uid']) {
		      		$fields = array_keys($user);
		    	}else {
		      		$fields = array('uid', 'username', 'password', 'sex', 'email', 'qq', 'msn', 'birthday', 'tel', 'phone', 'theme', 'signature', 'status', 'timezone', 'language', 'picture', 'groupid', 'authkey', 'lastlogin', 'regtime', 'logincount', 'ip');
		    	}
	  	}
		return $fields;
	}
	
}

class Tree {   
	public $data=array();   
	public $cateArray=array();   
	  
	function Tree(){}
	
	function setNode ($id, $parent, $value){   
		$parent = $parent?$parent:0;   
		$this->data[$id] = $value;   
		$this->cateArray[$id] = $parent;   
	}
	
	function getChildsTree($id=0){
		$childs=array();
		foreach ($this->cateArray as $child=>$parent){
			if ($parent==$id){
				$hasChild = $this->getChild($child);
				if(empty($hasChild)) {
					$childs[$child]=$this->getValue($child);
				}else{
					$childs[$child]=$this->getValue($child);
					$childs[$child]['subs']=$this->getChildsTree($child);
				}
			}
		}
		return $childs;   
	}
	
	function getChilds($id=0){
		$childArray=array();   
		$childs=$this->getChild($id);   
		foreach ($childs as $child){
			$childArray[]=$child;   
			$childArray=array_merge($childArray,$this->getChilds($child));   
		}
		return $childArray;   
	}
	
	function getChild($id){
		$childs=array();
		foreach ($this->cateArray as $child=>$parent){
			if ($parent==$id){
				$childs[$child]=$child;
			}
		}
		return $childs;
	}
	
	function getNodeLever($id){
		$parents=array();
		if (key_exists($this->cateArray[$id],$this->cateArray)){
			$parents[]=$this->cateArray[$id];
			$parents=array_merge($parents,$this->getNodeLever($this->cateArray[$id]));
		}
		return $parents;
	}
	
	function getLayer($id,$preStr=''){
		return str_repeat($preStr,count($this->getNodeLever($id)));
	}
	
	function getValue ($id){
		return $this->data[$id];   
 	}
 }
?>